//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<CTechnique10.cpp>
///	@path	~/src/graphics/dx10/
///	@date	2008/12/20
///	@desc	.

#include "config/config.h"

#include "lib/system/thread_debug.h"

#include "graphics/DxHelpers.h"
#include "graphics/IGeometry.h"
#include "graphics/dx10/CTechnique10.h"

namespace xeres {

	IMPL_IOBJECT_CLASS( CTechnique10 );

	// ctor
	CTechnique10::CTechnique10( RefWeak<IEffect> effect , ID3D10EffectTechnique * technique )
		: m_effect( effect )
		, m_pTechnique( technique )
	{
		memset( &m_desc , 0 , sizeof(D3D10_TECHNIQUE_DESC) );

		// get description
		HRESULT hr = S_OK;
		hr = m_pTechnique->GetDesc( &m_desc );
		if( FAILED(hr) )
		{
			TRACE_ERROR( _S("CTechnique10::Construct: Failed to get desc: %s.") , d3d_get_err( hr ) );
			FATAL_ABORT( _S("Failed to get technique description.") );
		}

		// get input signature
		D3D10_PASS_DESC PassDesc;
		m_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
		m_inputSignature = PassDesc.pIAInputSignature;
		m_signatureSize = PassDesc.IAInputSignatureSize;

		// convert name
		mbs_to_wcs( AString( m_desc.Name ) , m_name );
	}

	// dtor
	CTechnique10::~CTechnique10( void )
	{
		// clear cache if needed
		if( m_effect.IsValid() )
		{
			m_effect->UnusedTechnique( this );
		}
	}
	// GetVariableCount
	size_t CTechnique10::GetVariableCount( void )
	{
		return m_effect->GetVariableCount();
	}

	// GetVariableByIndex
	RefPass< IShaderVariable > CTechnique10::GetVariableByIndex( size_t index )
	{
		return m_effect->GetVariableByIndex( index );
	}
	// GetVariableByName
	RefPass< IShaderVariable > CTechnique10::GetVariableByName( const AString& name )
	{
		return m_effect->GetVariableByName( name );
	}
	// GetVariableBySemantic
	RefPass< IShaderVariable > CTechnique10::GetVariableBySemantic( const AString& semantic )
	{
		return m_effect->GetVariableBySemantic( semantic );
	}

	// get technique name
	const WString& CTechnique10::GetName( void )
	{
		return m_name;
	}

	// get pass count
	size_t CTechnique10::GetPassCount( void )
	{
		return m_desc.Passes;
	}
	// GetEffect
	RefWeak<IEffect> CTechnique10::GetEffect( void )
	{
		return m_effect;
	}

	// Begin
	void CTechnique10::Begin( uint pass , RenderContext& rc )
	{
		XS_ASSERT( pass < m_desc.Passes );
		m_pTechnique->GetPassByIndex( pass )->Apply(0);
	}

	// End
	void CTechnique10::End( uint& pass , RenderContext& rc )
	{
		++pass;
		if( pass >= m_desc.Passes )
			pass = 0;
	}
	// Draw
	void CTechnique10::Draw( RenderContext& rc , RefWeak<IGeometry> geometry )
	{
		geometry->EstablishBuffer( rc );
		UINT total = 0;
		for( UINT i = 0 ; i < m_desc.Passes ; ++i )
		{
			m_pTechnique->GetPassByIndex( i )->Apply(0);
			geometry->Draw( rc );
		}
	}

} // namespace xeres
